// @ts-nocheck
import camera from '@ohos.multimedia.camera';
import hilog from '@ohos.hilog';
import image from '@ohos.multimedia.image';
import fileio from '@ohos.fileio';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import prompt from '@ohos.prompt'
import deviceManager from '@ohos.distributedHardware.deviceManager';
import media from '@ohos.multimedia.media';
import { Logger } from './Logger';

const domain = 0
const app_tag = 'CameraApp'
const tag = '[CameraUtil]'

export enum CameraMode {
    photo = "photo",
    video = "video"
}

export interface CameraOption {
    photoProfile?: camera.Profile
    videoProfile?: camera.VideoProfile
    previewProfile?: camera.Profile
    cameraDevice?: camera.CameraDevice
    controller?: any
}

export interface CameraCallback {
    cameraManagerCameraStatus?: (cameraStatusInfo: camera.CameraStatusInfo) => void
    cameraManagerCameraMute?: (curMuted: boolean) => void
    cameraInputError?: (err) => void
    captureSessionFocusStateChange?: (focusState: camera.FocusState) => void
    captureSessionError?: (err) => void
    previewFrameStart?: () => void
    previewFrameEnd?: () => void
    previewError?: (err) => void
    photoCaptureStart?: (captureId: number) => void
    photoFrameShutter?: (frameShutterInfo: camera.FrameShutterInfo) => void
    photoCaptureEnd?: (captureEndInfo: camera.CaptureEndInfo) => void
    photoError?: (err) => void
    videoFrameStart?: () => void
    videoFrameEnd?: () => void
    videoError?: (err) => void
}

export interface CameraDeviceInfo {
    cameraDevice: camera.CameraDevice,
    cameraOutputCapability: camera.CameraOutputCapability,
    cameraDeviceName: string
}

export class CameraUtil {
    private lock = new class Lock {
        lockList = null

        public async lock() {
            if (this.lockList === null) {
                this.lockList = []
            }
            else {
                return new Promise(res => this.lockList.push(res))
            }
        }

        public unlock() {
            if (this.lockList.length) {
                this.lockList.shift()()
            }
            else {
                this.lockList = null
            }
        }
    }
    private option: CameraOption = {
        photoProfile: undefined,
        videoProfile: undefined,
        previewProfile: undefined,
        cameraDevice: undefined,
        controller: undefined
    }
    private ctx = undefined
    public cameraCallback: CameraCallback = {}
    private cameraManager: camera.CameraManager = null
    private cameraInput: camera.CameraInput = null
    private previewOutput: camera.PreviewOutput = null
    private photoOutput: camera.PhotoOutput = null
    private videoOutput: camera.VideoOutput = null
    private captureSession: camera.CaptureSession = null
    private cameraDeviceList: Array<CameraDeviceInfo> = []
    private imageReceiver: image.ImageReceiver = null
    private deviceManager: deviceManager.DeviceManager = null
    private medLib: mediaLibrary.MediaLibrary = null
    private photoPath: string = null
    private lastPhotoTime: number = 0


    private VideoPrepareFile:mediaLibrary.FileAsset = null
    private avProfile
    private avConfig
    private AVRecorder:media.AVRecorder = null
    private fdNumber:number

    /**
     * 初始化工具类,赋予相机配置初始值
     * */
    public async initCameraUtil(ctx) {
        Logger.i(`${tag} initCameraUtil 1`)
        await this.lock.lock()
        Logger.i(`${tag} initCameraUtil 2`)
        if (this.cameraManager) {
            Logger.i(`${tag} initCameraUtil 3`)
            this.lock.unlock()
            return
        }
        Logger.i(`${tag} initCameraUtil 4`)
        this.ctx = ctx
        // deviceManager.createDeviceManager("com.example.camerastage", (err, device) => {
        //     Logger.i(`${tag} deviceManager.createDeviceManager err ${JSON.stringify(err)}`)
        //     Logger.i(`${tag} deviceManager.createDeviceManager device ${JSON.stringify(device)}`)
        //     this.deviceManager = device
        // })
        Logger.i(`${tag} initCameraUtil 5`)

        this.cameraManager = camera.getCameraManager(ctx)
        if (!this.cameraManager) {
            hilog.error(domain, app_tag, `${tag} camera.getCameraManager fail,param ${JSON.stringify(ctx)}`)
        }
        else {
            Logger.i(`${tag} camera.getCameraManager successful`)
            this.cameraManager.on("cameraStatus", (err, cameraStatusInfo) => {
                Logger.i(`${tag} cameraManager.on.cameraStatus err=${JSON.stringify(err?.camera?.cameraId)} ${JSON.stringify(err)}`)
                Logger.i(`${tag} cameraManager.on.cameraStatus data=${JSON.stringify(cameraStatusInfo)}`)
                this.cameraCallback.cameraManagerCameraStatus && this.cameraCallback.cameraManagerCameraStatus(cameraStatusInfo)
            })
            this.cameraManager.on("cameraMute", (err, cameraMute) => {
                Logger.i(`${tag} cameraManager.on.cameraMute err=${JSON.stringify(err)}`)
                Logger.i(`${tag} cameraManager.on.cameraMute data=${JSON.stringify(cameraMute)}`)
                this.cameraCallback.cameraManagerCameraMute && this.cameraCallback.cameraManagerCameraMute(cameraMute)
            })
            this.getCameraDeviceList(true)
        }
        this.lock.unlock()
    }

    /**
     * 获取相机列表,可更新
     * */
    public getCameraDeviceList(update: boolean = false) {
        if(!this.cameraManager) {
            return this.cameraDeviceList
        }
        if (!update) {
            return this.cameraDeviceList
        }
        let tmp = []
        let cameras = this.cameraManager.getSupportedCameras()
        Logger.i(`${tag} cameraManager.getSupportedCameras length ${JSON.stringify(cameras?.length)}`)
        cameras.forEach(item => {
            let caps = this.cameraManager.getSupportedOutputCapability(item)
            tmp.push({ cameraDevice: item, cameraOutputCapability: caps, cameraDeviceName: item.cameraId })
            Logger.i(`${tag} cameraDevice ${item.cameraId}  ${item.connectionType}  ${item.cameraType}  ${item.cameraPosition}  ${JSON.stringify(caps.videoProfiles)} ${JSON.stringify(caps.previewProfiles)} ${JSON.stringify(caps.photoProfiles)}`)
        })
        this.cameraDeviceList = tmp
        if (this.cameraDeviceList.length > 0 && !this.option.cameraDevice) {
            this.option.cameraDevice = this.cameraDeviceList[0].cameraDevice
            this.option.photoProfile = this.cameraDeviceList[0].cameraOutputCapability.photoProfiles[0]
            this.option.previewProfile = this.cameraDeviceList[0].cameraOutputCapability.previewProfiles[0]
            this.option.videoProfile = this.cameraDeviceList[0].cameraOutputCapability.videoProfiles[0]
        }

        return this.cameraDeviceList
    }

    /**
     * 获取当前显示相机信息
     * */
    public getCurrentCameraDevice() {
        return this.option.cameraDevice
    }

    /*
     * 获取当前相机配置参数
     */
    public getOption() {
        return this.option
    }

    /**
     * 开启相机
     * */
    public async openCamera(locked:boolean = true, option?: CameraOption,ctx) {
        if(locked) {
            await this.lock.lock()
        }
        option && Object.assign(this.option, option)
        if (!this.checkOption()) {
            hilog.error(domain, app_tag, `${tag} openCamera fail, some param in option is null ${JSON.stringify(this.option)}`)
            this.lock.unlock()
            return
        }
        if (this.captureSession) {
            this.lock.unlock()
            return
        }

        try {
            this.ctx = ctx
            Logger.i(`${tag} openCamera 1`)
            this.option.controller.setXComponentSurfaceSize({ surfaceWidth: this.option.previewProfile.size.width, surfaceHeight: this.option.previewProfile.size.height })
            let previewSurfaceId = this.option.controller.getXComponentSurfaceId()
            this.previewOutput = this.cameraManager.createPreviewOutput(this.option.previewProfile, previewSurfaceId)
            Logger.i(`${tag} cameraManager.createPreviewOutput ${JSON.stringify(this.option.previewProfile)} ${previewSurfaceId}`)
            //image
            this.imageReceiver = image.createImageReceiver(this.option.photoProfile.size.width, this.option.photoProfile.size.height, this.option.photoProfile.format, 8)
            this.imageReceiver.on("imageArrival", (err) => {
                Logger.e(`${tag} imageArrival ${JSON.stringify(err)}`)
                Logger.i(`${tag} imageArrival`)
                this.imageReceiver.readNextImage((err, img) => {
                    Logger.e(`${tag} readNextImage ${JSON.stringify(err)}`)

                    Logger.i(`${tag} readNextImage ${JSON.stringify(img)}`)
                    img.getComponent(4, async (err, component) => {
                        Logger.e(`${tag} getComponent ${JSON.stringify(err)}`)

                        Logger.i(`${tag} getComponent ${JSON.stringify(component)}`)
                        if (component === undefined) {
                            return
                        }

                        if (component.byteBuffer) {
                            let buffer = new ArrayBuffer(4096)
                            buffer = component.byteBuffer
                            this.saveBufferToFile(buffer,ctx)
                        }
                        img.release()
                    })
                })
            })
            let photoSurfaceId = await this.imageReceiver.getReceivingSurfaceId()
            this.photoOutput = this.cameraManager.createPhotoOutput(this.option.photoProfile, photoSurfaceId)
            Logger.i(`${tag} cameraManager.createPhotoOutput ${JSON.stringify(this.option.photoProfile)}`)

            this.cameraInput = this.cameraManager.createCameraInput(this.option.cameraDevice)
            Logger.i(`${tag} cameraManager.createCameraInput ${JSON.stringify(this.option.cameraDevice.cameraId)}`)
            await this.cameraInput.open()
            Logger.i(`${tag} cameraInput.open`)

            this.captureSession = this.cameraManager.createCaptureSession()
            Logger.i(`${tag} cameraManager.createCaptureSession`)
            this.captureSession.beginConfig()
            Logger.i(`${tag} captureSession.beginConfig`)

            this.captureSession.addInput(this.cameraInput)
            Logger.i(`${tag} captureSession.addInput cameraInput`)
            this.captureSession.addOutput(this.previewOutput)
            Logger.i(`${tag} captureSession.addOutput previewOutput`)
            this.captureSession.addOutput(this.photoOutput)
            Logger.i(`${tag} captureSession.addOutput photoOutput`)
//            this.captureSession.addOutput(this.videoOutput)
//            Logger.i(`${tag} captureSession.addOutput videoOutput`)

            await this.captureSession.commitConfig()
            Logger.i(`${tag} captureSession.commitConfig`)
            await this.captureSession.start()
            Logger.i(`${tag} captureSession.start`)
        }
        catch (e) {
            hilog.error(domain, app_tag, `${tag} openCamera fail, err ${JSON.stringify(e)}`)
        }
        if(locked) {
            this.lock.unlock()
        }
    }

    /**
     * 配置会话的Output，photo<==>av 变更
     * */
    async changeCaptureSession(isPhotoMode){
        try{
//            await this.captureSession.release().then(() => {
//                Logger.i(tag+'Promise returned to indicate that the CaptureSession instance is released successfully.');
//            }).catch((err) => {
//                console.error(tag+`Failed to release the CaptureSession instance ${err.code}`);
//            });
//            this.captureSession = await this.cameraManager.createCaptureSession()
            await this.captureSession.stop()
            Logger.i(`${tag} captureSession.stop`)
            await this.captureSession.beginConfig()
            Logger.i(`${tag} captureSession.beginConfig`)
//            await this.captureSession.addInput(this.cameraInput)
//            Logger.i(`${tag} captureSession.addInput cameraInput`)
//            await this.captureSession.addOutput(this.previewOutput)
//            Logger.i(`${tag} captureSession.addOutput previewOutput`)

            if (isPhotoMode) {
                await this.captureSession.removeOutput(this.videoOutput)
                let photoSurfaceId = await this.imageReceiver.getReceivingSurfaceId()
                this.photoOutput = await this.cameraManager.createPhotoOutput(this.option.photoProfile, photoSurfaceId)
                Logger.i(`${tag} cameraManager.createPhotoOutput ${JSON.stringify(this.option.photoProfile)}`)

                await this.captureSession.addOutput(this.photoOutput)
                Logger.i(`${tag} captureSession.addOutput photoOutput`)

            }
            else{
                // 从会话中移除拍照输出流
                await this.captureSession.removeOutput(this.photoOutput)
                Logger.i(`${tag} captureSession.addOutput videoOutput`)

                if (this.videoOutput) {
//                    await this.captureSession.removeOutput(this.videoOutput)
                    Logger.i(`${tag} captureSession.removeOutput videoOutput`)
                }
                if (this.AVRecorder) {
                    await this.AVRecorderStop()
                    Logger.i(`${tag} this.AVRecorderStop`)
                }
                await this.avProfileAndListen()
                Logger.i(`${tag} avProfileAndListen`)
                // 向会话中添加录像输出流
                await this.captureSession.addOutput(this.videoOutput)
                Logger.i(`${tag} captureSession.addOutput videoOutput`)
            }
            await this.captureSession.commitConfig()
            Logger.i(`${tag} captureSession.commitConfig`)
            await this.captureSession.start()
            Logger.i(`${tag} captureSession.start`)

        }catch(e){
            hilog.error(domain, app_tag, `${tag} openCamera fail, err ${JSON.stringify(e)}`)
        }


    }




    /**
     * 配置音视频录制相关参数并创建对象开启监听
     * */
    async avProfileAndListen(){
        // 音视频录制相关参数配置
        this.avProfile = {
            audioBitrate: 48000,
            audioChannels: 2,
            audioCodec: 'audio/mp4a-latm',
            audioSampleRate: 48000,
            durationTime: 1000,
            fileFormat: 'mp4',
            videoBitrate: 48000,
            videoCodec: 'video/avc',
            videoFrameWidth: 640,
            videoFrameHeight: 480,
            videoFrameRate: 30
        }
        Logger.i(tag+'case createAVRecorder called avProfile'+JSON.stringify(this.avProfile));
        if (this.fdNumber) {
            await this.VideoPrepareFile?.close(this.fdNumber,()=>{})
        }
        let fd = await this.createVideoFd()
        Logger.i(tag+'case createAVRecorder called fd'+JSON.stringify(fd));

        this.avConfig = {
            audioSourceType: 1,
            videoSourceType: 1,
            profile: this.avProfile,
            url: fd,
            orientationHint: 0,
//            maxSize: 100,
//            maxDuration: 500,
            rotation: 0
        }
        Logger.i(tag+'case createAVRecorder called avConfig'+JSON.stringify(this.avConfig));

        // 创建AVRecorder对象
        await media.createAVRecorder().then((recorder) => {
            Logger.i(tag+'case createAVRecorder called');
            if (typeof (recorder) != 'undefined') {
                this.AVRecorder = recorder;
                Logger.i(tag+'createAVRecorder success');
            } else {
                Logger.i(tag+'createAVRecorder failed');
            }
        }, this.failureCallback).catch(this.catchCallback);

        // 对象创建成功后创建on('stateChange')和on('error')监听回调用于监听状态机变化和错误上报
        this.AVRecorder.on('stateChange', async (state, reason) => {
            Logger.i(tag+'case state has changed, new state is :' + state);
            switch (state) {
            // 用户可以根据需求在不同状态设置自己想要进行的行为
                case 'idle':
                // 调用rest接口后触发idle状态；create后也在idle状态
                    break;
                case 'prepared':
                // 调用prepare接口后触发prepared状态;
                    break;
                case 'started':
                // 调用start接口后触发started状态;
                    break;
                case 'paused':
                // 调用pause接口后触发paused状态;
                    break;
                case 'stopped':
                // 调用stop接口后触发stopped状态;
                    break;
                case 'released':
                // 调用release接口后触发released状态;
                    break;
                case 'error':
                // error状态说明底层出错，用户需排查错误，重新创建avRecorder;
                    break;
                default:
                    Logger.i(tag+'case state is unknown');
            }
        });
        this.AVRecorder.on('error', (err) => {
            // 监听非接口类错误上报
            Logger.i(tag+'case avRecorder.on(error) called, errMessage is ' + err.message);
        });
        // 调用prepare完成音频录制前的准备工作；底层实际是根据prepare的入参来判断是音频录制、视频录制还是音视频录制
        await this.AVRecorder.prepare(this.avConfig).then(() => {
            Logger.i(tag+'prepare success');
        }, this.failureCallback).catch(this.catchCallback);
        let surfaceID
        // 包含视频的录制需要调用getInputSurface接口，并将返回值surfaceID传递给camera相关接口
        surfaceID = await this.AVRecorder.getInputSurface()
        Logger.i(tag+'surfaceID : '+surfaceID);

        this.videoOutput = this.cameraManager.createVideoOutput(this.option.videoProfile,surfaceID)
        Logger.i(`${tag} cameraManager.createVideoOutput ${JSON.stringify(this.option.videoProfile)}`)

    }

    /**
     * 启动视频录制
     * */
    async AVRecorderStart(){
        await this.videoOutput.start().then(() => {
            Logger.i(tag+'Promise returned to indicate that start method execution success.');
        }).catch((err) => {
            Logger.i(tag+'Failed to videoOutput start '+ err.code);
        });
        await this.AVRecorder.start().then(() => {
            Logger.i('start success');
        }, this.failureCallback).catch(this.catchCallback);
    }
    /**
     * 停止视频录制
     * */
    async AVRecorderStop(){
        await this.AVRecorder.stop().then(() => {
            Logger.i(tag+'stop AVRecorder success');
        }).catch((err) => {
            Logger.i(tag+'stop AVRecorder failed and catch error is ' + err.message);
        });
        await this.AVRecorder.reset().then(() => {
            Logger.i(tag+'reset AVRecorder success');
        }).catch((err) => {
            Logger.i(tag+'reset AVRecorder failed and catch error is ' + err.message);
        });
        await this.AVRecorder.release().then(() => {
            Logger.i(tag+'release AVRecorder success');
        }).catch((err) => {
            Logger.i(tag+'release AVRecorder failed and catch error is ' + err.message);
        });

        await this.videoOutput.stop().then(() => {
            Logger.i(tag+'Promise returned to indicate that stop method execution success.');
        }).catch((err) => {
            Logger.i(tag+'Failed to videoOutput stop '+ err.code);
        });
        await this.VideoPrepareFile.close(this.fdNumber).then(() => {
            Logger.i(tag+'asset.close successfully');
        }).catch((closeErr) => {
            console.error(tag+'asset.close fail, closeErr: ' + closeErr);
        });

    }
    /**
     * 关闭监听并释放资源
     * */
    async AVRecorderClose(){
        // 关闭监听回调，如果用户不自行调用off接口，在调用release后，设置的回调接口也会无效
        this.AVRecorder.off('stateChange');
        this.AVRecorder.off('error');
        this.VideoPrepareFile.close(this.fdNumber)

        // 释放视频录制相关资源并释放camera对象相关资源
        await this.AVRecorder.release().then(() => {
            Logger.i('release success');
        }, this.failureCallback).catch(this.catchCallback);
    }

    /**
     * 关闭相机
     * */
    public async closeCamera(locked:boolean = true) {
        if(locked) {
            await this.lock.lock()
        }

        if (!this.photoOutput) {
            this.lock.unlock()
            return
        }

        try {
            await this.captureSession.stop()
            Logger.i(`${tag} captureSession.stop`)
            await this.cameraInput.close()
            Logger.i(`${tag} cameraInput.close`)
            await this.previewOutput.release()
            Logger.i(`${tag} previewOutput.release`)
            await this.photoOutput.release()
            Logger.i(`${tag} photoOutput.release`)
            await this.captureSession.release()
            Logger.i(`${tag} captureSession.release`)
            await this.imageReceiver.release()
            this.captureSession = null
            this.cameraInput = null
            this.previewOutput = null
            this.photoOutput = null
            this.imageReceiver = null
        }
        catch (error) {
            hilog.error(domain, app_tag, `${tag} closeCamera error ${JSON.stringify(error)}`)
        }
        if(locked) {
            this.lock.unlock()
        }
    }

    /**
     * 切换模式
     * */
    public async changeMode() {

    }

    /**
     * 切换摄像头
     * */
    public async switchCamera(option?: CameraOption) {
        await this.lock.lock()
        option && Object.assign(this.option, option)
        if (!this.checkOption()) {
            hilog.error(domain, app_tag, `${tag} switchCamera fail, some param in option is null ${JSON.stringify(this.option)}`)
            this.lock.unlock()
            return
        }
        await this.closeCamera(false)
        await this.openCamera(false)

        this.lock.unlock()
    }

    public async changeOption(option?: CameraOption) {
        await this.lock.lock()
        option && Object.assign(this.option, option)
        if (!this.checkOption()) {
            hilog.error(domain, app_tag, `${tag} changeOption fail, some param in option is null ${JSON.stringify(this.option)}`)
            this.lock.unlock()
            return
        }
        await this.closeCamera(false)
        await this.openCamera(false)

        this.lock.unlock()
    }

    /**
     * 拍照
     * */
    public takePicture() {

        if(!this.captureSession) {
            return
        }

        if (!this.photoOutput) {
            return
        }

        let t = Date.now()
        if(t - this.lastPhotoTime < 1000) {
            return
        }
        this.lastPhotoTime = t
        this.photoOutput.capture()
    }

    /**
     * 校验参数
     * */
    public checkOption() {
        return this.option.cameraDevice && this.option.controller
    }

    /**
     * 存储图片
     * */
    public async  saveBufferToFile(buffer,ctx) {
        this.medLib = mediaLibrary.getMediaLibrary(ctx)
        if (!this.photoPath) {
            this.photoPath = await this.medLib.getPublicDirectory(mediaLibrary.DirectoryType.DIR_IMAGE) + 'Camera/'
            Logger.i(`${tag} medLib.getPublicDirectory ${this.photoPath}`)
        }

        let displayName = this.getFileName(".jpg")
        Logger.i(`${tag} displayName ${displayName}`)
        let asset = await this.medLib.createAsset(mediaLibrary.MediaType.IMAGE, displayName, this.photoPath)
        if (asset) {
            asset.open("Rw").then(fd => {
                fileio.write(fd, buffer).then(() => {
                    asset.close(fd).then(async () => {
                        prompt.showToast({
                            message: '图片路径' + this.photoPath + displayName,
                            duration: 2000,
                        });
                        this.medLib.release()
                    }).catch(e => {
                        this.medLib.release()
                        hilog.error(domain, app_tag, `${tag} close ${displayName} fail ${JSON.stringify(e)}`)
                    })
                }).catch(e => {
                    this.medLib.release()
                    hilog.error(domain, app_tag, `${tag} write ${displayName} fail ${JSON.stringify(e)}`)
                })
            }).catch(e => {
                hilog.error(domain, app_tag, `${tag} open ${displayName} fail ${JSON.stringify(e)}`)
                this.medLib.release()
            })
        }
        else {
            Logger.i(`${tag} medLib.createAsset fail ${JSON.stringify(asset)}`)
            this.medLib.release()
        }
    }
    /**
     * 获取视频的fdNumber
     * */
    public async createVideoFd(): Promise<string> {
        const displayName = this.getFileName('.mp4')
        const media = mediaLibrary.getMediaLibrary(this.ctx)
        const fileKeyObj = mediaLibrary.FileKey;
        const mediaType = mediaLibrary.MediaType.VIDEO;
        let publicPath: string = await media.getPublicDirectory(mediaLibrary.DirectoryType.DIR_VIDEO) + 'Camera/';

        try {
            const dataUri = await media.createAsset(mediaType, displayName, publicPath);
            if (dataUri != undefined) {
                const args = dataUri.id.toString();
                const fetchOp = {
                    selections : fileKeyObj.ID + "=?",
                    selectionArgs : [args],
                }
                const fetchFileResult = await media.getFileAssets(fetchOp);
                this.VideoPrepareFile = await fetchFileResult.getFirstObject();
                this.fdNumber = await this.VideoPrepareFile.open('rw');
                Logger.i(tag+"fd : "+("fd://" + this.fdNumber.toString()))
                return "fd://" + this.fdNumber.toString()
            }
        } catch(err) {

        }
    }


    public getFileName(suffix = "") {
        let d = new Date()
        let pre = 'VID_'
        let padHead = (n) => {
            return n < 10 ? `0${n}` : n
        }
        let year = d.getFullYear()
        let mon = padHead(d.getMonth() + 1)
        let day = padHead(d.getDate())
        let h = padHead(d.getHours())
        let m = padHead(d.getMinutes())
        let s = padHead(d.getSeconds())
        return `${pre}${year}${mon}${day}${h}${m}${s}${suffix}`
    }



    // async getFd() {
    //     let fdNumber = await createVideoFd()
    //     this.testFdNumber = "fd://" + fdNumber.toString();
    // }

    // 当promise接口发生错误上上报的错误回调接口
    failureCallback(error) {
        Logger.i(tag+'error happened, error message is ' + error.message);
    }

    // 当promise接口发生异常时，系统调用的错误回调接口
    catchCallback(error) {
        Logger.i(tag+'catch error happened, error message is ' + error.message);
    }

}